package com.cycrix.sensor;

import java.io.IOException;
import java.net.Socket;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.cycrix.tcp.TcpConnection;
import com.cycrix.tcp.TcpDummy;
import com.cycrix.tcp.TcpObject;
import com.cycrix.tcp.TcpServer;
import com.cycrix.tcp.TcpText;

public class TCPActivity extends Activity {

	private TextView _txtOutput;
	private Button _btnClose;
	private Button _btnClear;
	private Button _btnSend;
	private EditText _edtText;
	private TcpServer _server;
	private TcpConnection _con;
	
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.tcp_screen);

		_txtOutput = (TextView) findViewById(R.id.txtOutput);
		_edtText = (EditText) findViewById(R.id.edtText);
		_btnClose = (Button) findViewById(R.id.btnClose);
		_btnClose.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				try {
					_con.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		_btnSend = (Button) findViewById(R.id.btnSend);
		_btnSend.setOnClickListener(new OnClickListener() {
			
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				try {
					_con.send(new TcpText(_edtText.getText().toString()));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		
		_btnClear = (Button) findViewById(R.id.btnClear);
		_btnClear.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				_txtOutput.setText("");
			}
		});

		try {
			_server = new TcpServer(12345, new  Handler() {
				@Override
				public void handleMessage(Message msg) {
					switch (msg.what) {
					case TcpServer.DID_ACCEPT:
						try {
							if (_con != null)
								_con.close();

							_con = new TcpConnection((Socket) msg.obj, new Handler() {
								public void handleMessage(Message msg) {
									switch (msg.what) {
									case TcpConnection.DID_RECEIVE:
										HandleRecv((TcpObject) msg.obj);
										break;
									case TcpConnection.DID_CLOSE:
										println("<<<connection closed>>>");
										break;
									case TcpConnection.DID_ERROR:
										println("<<<connection error>>>");
										break;
									}
								}
							});

							println("<<<Connection accepted" + _con._socket.getRemoteSocketAddress().toString() + ">>>");
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						break;
						
					case TcpServer.DID_ERROR:
						println("<<<serve error>>>");
						break;
					}
				}
			});
		} catch (IOException e) {
			finish();
		}
		
		
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		try {
			_server.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			_con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void println(String s) {
		CharSequence origin = _txtOutput.getText();
		System.currentTimeMillis();
		_txtOutput.setText(s + "\n" + origin);
	}
	
	private int _recvSize = 0;
	private long _lastTime = System.currentTimeMillis();
	private int _recvPacket = 0;
	private int _lastRecvSize = 0;
	private int _lastRecvPacket = 0;
	private void HandleRecv(TcpObject tcpObj) {
		switch (tcpObj.GetType()) {
		case TcpConnection.ENUM_TEXT:
			println(((TcpText) tcpObj).GetText());
			break;
		case TcpConnection.ENUM_DUMMY:
		{
			int size = ((TcpDummy) tcpObj).GetSize();
			_recvSize += size;
			_recvPacket++;
			
			long now = System.currentTimeMillis();
			long period = now - _lastTime;
			if (true) {
				// Update info
				TextView txtRecv = (TextView) findViewById(R.id.txtRecv);
				TextView txtPacket = (TextView) findViewById(R.id.txtPacket);
				TextView txtSpeed = (TextView) findViewById(R.id.txtSpeed);
				TextView txtRate = (TextView) findViewById(R.id.txtRate);
				
				txtRecv.setText("Recv: " + ConvenUnit(_recvSize).toString());
				txtPacket.setText("Packet: " + Integer.toString(_recvPacket)
						+ " Packets");

				txtSpeed.setText("Speed: "
						+ ConvenUnit(((long)_recvSize - _lastRecvSize) * 1000 / period)
						.append("/s").toString());
				txtRate.setText("Rate: " +
						Integer.toString(_recvPacket - _lastRecvPacket) +
						"Packet/s");
				
				// update last
				_lastTime = now;
				_lastRecvPacket = _recvPacket;
				_lastRecvSize = _recvSize;
			}
		}
		break;
		}
	}
	
	private StringBuilder ConvenUnit(long size) {
		StringBuilder builder = new StringBuilder();
		
		String[] unitName = new String[] {" Byte", " KB", " MB"};
		
		int powerStep = 1024;
		int power = 1;
		int unit = 0;
		
		for (int i = 0; i < unitName.length; i++) {
			if (size >= power * powerStep) {
				power *= powerStep;
				unit++;
			} else {
				break;
			}
		}
		
		float temp = (float) ((int) (((float) size / power) * 100)) / 100;
		if (temp <= 0)
		{
			int a = 0;
		}
		
		builder.append(temp);
		builder.append(unitName[unit]);
		
		return builder;
	}
}